{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "生成模拟订单数据（9个特征）...\n",
      "\n",
      "=== 性能测试 ===\n",
      "测试规模: 100, GM时间: 0.32ms, MK时间: 0.28ms\n",
      "测试规模: 300, GM时间: 0.96ms, MK时间: 0.64ms\n",
      "测试规模: 1000, GM时间: 2.77ms, MK时间: 4.20ms\n",
      "测试规模: 3000, GM时间: 14.72ms, MK时间: 6.41ms\n",
      "测试规模: 5000, GM时间: 15.11ms, MK时间: 18.36ms\n",
      "\n",
      "=== 准确率验证 ===\n",
      "\n",
      "广义映射分类报告:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "       False       0.71      0.99      0.83      3545\n",
      "        True       0.55      0.03      0.06      1455\n",
      "\n",
      "    accuracy                           0.71      5000\n",
      "   macro avg       0.63      0.51      0.44      5000\n",
      "weighted avg       0.67      0.71      0.60      5000\n",
      "\n",
      "\n",
      "马尔科夫链分类报告:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "       False       0.00      0.00      0.00      3545\n",
      "        True       0.29      1.00      0.45      1455\n",
      "\n",
      "    accuracy                           0.29      5000\n",
      "   macro avg       0.15      0.50      0.23      5000\n",
      "weighted avg       0.08      0.29      0.13      5000\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\ThinkPad\\anaconda3\\lib\\site-packages\\sklearn\\metrics\\_classification.py:1221: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n",
      "  _warn_prf(average, modifier, msg_start, len(result))\n"
     ]
    },
    {
     "data": {
      "image/png": "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IiIiUhSUYBWBefPmceaZZ7LrrrtywAEHcNBBBzF06NDY4nnhhRe45JJLAOjXrx8vvfTSVh+zUaNG/P3330mXH3LIIZssa968OU2bNt3qc2Z166238vHHHxfIsdydI444gqVLl2YuGzp0KGbGzz//XCDnSGbixInsu+++7L777lx22WWEPvWbGjhwIM2bN8+8lSlThsmTJwNw8803s9NOO7HNNttsss/jjz/O888/X2hxi4iIiEigBCuLgQOhUSMoUyb8HThw647n7px88skceuihTJ8+nYkTJzJ48GBmz55dEOFma926dXnarlevXpxzzjmFGsuyZcv4448/AAp1RL477riDo446qkCONWzYMJo1a8a2226buWzQoEG0a9eOwYMHF8g5kvnPf/5D//79+fXXX/n111/58MMPN9umW7duTJ48mcmTJ/Pyyy/TqFEjmjdvDkDHjh0ZP378Zvucf/75PProo4UWt8gmdtwRzMCMtMMPz7zPjjvGHZmIiEihU4KVYOBA6NkTZs4E9/C3Z8+tS7JGjRpFhQoV6NWrV+ayhg0bcumllwKwfv16rr32Wlq1asV+++3H008/DUB6ejppaWmcfvrp7LXXXnTr1i2zNmPixIkcdthhHHDAARx99NHMnRvmuUxLS+Omm27isMMO45FHHuG9997jwAMPZP/99+eoo45i3rx5m8XXp08f+vbty9y5czepFSlbtiwzZ85kwYIFnHbaabRq1YpWrVoxbtw4ABYuXEiHDh3Yf//9ueiii5LWtGQ444wzGDJkCBCSlK5dN46EPGPGDA455BBatGhBixYt+PzzzzOf/6GHHsopp5xCkyZN6NWrFxs2bABgm2224eqrr6ZFixYceeSRLFiwAIBzzz2XN954Awg1Z7fddhstWrRg3333zax1WrBgAe3bt6dFixZcdNFFNGzYMGnN28CBAznppJMyHy9fvpxx48YxYMCATRKs9evXc80117Dvvvuy33778dhjjwEwYcIEDj74YJo1a0br1q1ZtmxZtuWTYe7cuSxdupSDDjoIM+Occ87h7bffznGfrOXZpk0b6tatu9l2VapUoVGjRkmTL5ECl+SzJsflIiIipUipH6Y90RVXwOTJsH59ZcqW3Xz9l1/C6tWbLlu5Enr0gGeeSX7M5s3hf//L/pxTpkyhRYsW2a4fMGAA1atXZ8KECaxevZq2bdvSoUMHAL755humTJlCvXr1aNu2LePGjePAAw/k0ksv5Z133qFWrVoMGTKEm2++meeeew6AxYsXM3r0aAD++ecfvvzyS8yMZ599lvvvv58HH3wwaRx169bNbGb2xBNPMHr0aBo2bMiZZ57JlVdeSbt27Zg1axZHH300P/30E7fffjvt2rXj1ltv5YMPPqB///7ZPsfTTz+dc889l2uuuYb33nuPgQMH8vLLLwNQu3ZtRo4cSaVKlfj111/p2rUrX3/9NQDjx4/nxx9/pGHDhhxzzDG89dZbnH766axYsYIWLVrw4IMPcscdd3D77bfz+OOPb3beHXbYgUmTJvHkk0/St29fnn32WW6//XaOOOIIbrzxRj788MNs4x43blxmsgvw9ttvc8wxx7DHHnuw3XbbMWnSJFq0aEH//v35/fff+eabbyhXrhyLFi1izZo1dO7cmSFDhtCqVSuWLl1K5cqVmTp1Kp07d056vvT0dP78808aNGiQuaxBgwb8+eef2ZYrwJAhQ3jnnXdy3CZDy5Yt+eyzz2jdunWethcRERGR/EupBCs3WZOr3JZvid69ezN27FgqVKjAhAkTGDFiBN99911mzcuSJUv49ddfqVChAq1bt878wt28eXNmzJhBjRo1+OGHH2jfvj0QalASaywSv8DPnj2bzp07M3fuXNasWZOnuY7GjRvHs88+y2effQbAxx9/zI8//pi5funSpSxbtowxY8bw1ltvAXD88cdTs2bNbI+53XbbUbNmTQYPHszee+9NlSpVMtetXbuWSy65hMmTJ1O2bFl++eWXzHWtW7dm1113BaBr166MHTuW008/nTJlymQ+z7POOotTTz016Xkzlh9wwAGZsY4dOzaz/9sxxxyTbdyLFi2iWrVqmTVPgwYN4oorrgCgS5cuDBo0iBYtWvDxxx/Tq1cvypUrl/lcv//+e+rWrUurVq0AMpsZ7rnnnplJbDLJagFzGuXvq6++okqVKnnuz1a7du1C7T8mIiIiIimWYGXUNC1b9m/SyWMbNQrNArNq2BDS07fsnPvssw9vvvlm5uMnnniCv//+m5YtWwLhS/Vjjz3G0Ucfvcl+6enpVKxYMfNx2bJlWbduHe7OPvvswxdffJH0fFWrVs28f+mll3LVVVdx4oknkp6eTp8+fXKMde7cufTo0YN33303c5CEDRs28MUXX1C5cuXNts/PEN+dO3emd+/evPDCC5ssf/jhh6lTpw7ffvstGzZsoFKlStkeP7vzZbc8o/wyyg6SJzHJlCtXLrNJ4sKFCxk1ahQ//PADZsb69esxM+6//37cfbPzJ1sG5FqD1aBBg0365s2ePZt69eplG+PgwYM3aR6Ym1WrViX9P4qIiIhIwVEfrAR33w0JlStAeHz33Vt+zCOOOIJVq1bx1FNPZS5buXJl5v2jjz6ap556irVr1wLwyy+/sGLFimyPt+eee7JgwYLMBGvt2rVMmTIl6bZLliyhfv36ALz44os5xrl27VrOOOMM7rvvPvbYY4/M5R06dNik+V1GDcyhhx7KwKhz2vDhw/nnn39yPP4pp5zCddddt1kiuWTJEurWrUuZMmV4+eWXWb9+fea68ePH8/vvv7NhwwaGDBlCu3btgJD0ZdT4vfrqq5nL86Jdu3a89tprAIwYMSLbuPfcc0+mT58OwBtvvME555zDzJkzmTFjBn/88Qe77LILY8eOpUOHDvTr1y8zgVu0aBF77bUXc+bMYcKECUAY5GPdunWZNVjJbjVq1KBu3bpUq1aNL7/8EnfnpZde2qQfWKINGzbw+uuv06VLlzw/919++aVQRm8U2UQ2n0ciIiKpQglWgm7doH//UGNlFv727x+Wbykz4+2332b06NHssssutG7dmu7du3PfffcBcMEFF9CkSRNatGhB06ZNueiii3IcAbBChQq88cYbXH/99TRr1ozmzZtnDgyRVZ8+fejUqROHHHIIO+ywQ45xfvXVV0yYMIHbbrstc6CLOXPm8Oijj/L111+z33770aRJE/r16wfAbbfdxpgxY2jRogUjRoxg5513zvH41apV4/rrr6dChQqbLL/44ot58cUXadOmDb/88ssmNXAHHXQQN9xwA02bNmWXXXbhlFNOAUIt3ZQpUzjggAMYNWoUt956a47nTnTbbbcxYsQIWrRowfDhwzOTmqyOP/540qNqy0GDBmWeO8Npp53Gq6++ygUXXMDOO+/MfvvtR7NmzXj11VepUKECQ4YM4dJLL6VZs2a0b9+eVatW5Sm+p556igsuuIDdd9+d3XbbjWOPPRaAd999d5PnOWbMGBo0aJDZhDLDddddR4MGDVi5ciUNGjTYpNZy3LhxBTbKokhSixfDySeHYViTqVOnKKMRERGJh7uXmtsBBxzgWf3444+bLVu6dOlmy1JdcSuTTz/91I8//vik66pWrbrFx121apWvXbvW3d0///xzb9asWdLt5syZ40cddVSxK5ctNWnSJD/rrLOSrkv2HsnNp59+upURlT4pXybr17sfd5x7uXLuY8dmLi6IcgG+9mJwjdnSW7JrkxSulH8/SkrS677oZXd9Sqk+WCKzZs3ijDPOYMOGDVSoUIFnshkesm7dulx44YUsXbo0aQ1XSfP3339z5513xh2GlGaffw4ffgiPPQZt28YdjYiISGyUYEmxlJaWRlpaWtJ1y5cv3+LjNm7cmG+++SZP255xxhl5mr+qJMgYdVKk0LRrF+bBUD8/ERFJceqDJSIiW27qVPjoo3B/331DB1YREZEUphosERHZMkuXhkEtFi+G337bfBhWERGRFFRoCZaZPQecAMx396bRsiHAntEmNYDF7t48yb4zgGXAemCdu7csrDhFRGQLbNgA3bvDr7/Cxx8ruRIREYkUZg3WC8DjwEsZC9w9c5ZVM3sQWJLD/oe7+9+FFp2IiGy5e+6Bt98OM7hn019SREQkFRVaguXuY8ysUbJ1ZmbAGcARhXV+EREpJJMmwa23hkkCL7ss7mhERESKlbj6YB0CzHP3X7NZ78AIM3PgaXfvn92BzKwn0BOgTp06mZPDZqhevfpmI8GtX78+6ehwVXffnTLz52+2fEPt2qyYNi2n55Ojbbfdls6dO2cOCb5u3ToaN25My5Ytef311/N8nM8++4xHH300X/vkZu3atdx111288847VKxYkcqVK3PTTTfRoUMH6taty9y5c/N8rGHDhvHzzz9z1VVX5Xmff//9l1NPPZX333+fsmXLAvD4449z++23M23aNKpXr57v55QXI0eO5Prrr2f9+vV07949acxDhgzh4YcfxsyoWrUqDz/8MPvuuy8ATz75JC+++CLuTvfu3enduzcAN998Mx06dOCwww4rlLgLw6pVqzZ73+Rm+fLl+d6ntEupMnGnznXXsSAtjQ2jR+e4aUqVi4iICPElWF2BQTmsb+vuc8ysNjDSzH529zHJNoySr/4ALVu29KxDe//000+bzWO0bNmy5HMbJUmuAMrMn79VcyFVrVqVqVOnUq5cOSpXrszw4cNp0KAB5cqVy/Nx161bR5UqVfK1T17ccMMNLFy4kK+++ooddtiBefPmMXr06Mxz5OdcnTt3zn2jLF566SU6depEjRo1MpcNHTqUVq1a8fHHH3Puuefm+5i5Wb9+Pddeey0jR46kQYMGtGrVik6dOtGkSZNNtmvSpAnDhw9n5513Zvjw4Vx55ZV89dVX/PDDD7z88st8/fXXVKhQgWOOOYbTTjuNxo0bc/XVV3PhhRdywgknFHjchaVSpUrsv//++donPT0922H0U1VKlMny5TB3LjRuDIcfzt552CUlykVERCRBkQ/TbmblgFOBIdlt4+5zor/zgaFA6wILIC2NyscdF/oMZNyefDJv+/7996b75eNLw7HHHssHH3wAwKBBg+jatWvmuvHjx3PwwQez//77c/DBBzN16lQAXnjhBTp16kTHjh3p0KHDJsebMGEC+++/P9OnT+eTTz5h//33Z9999+X8889n9erVDB8+nDPOOCNz+/T0dDp27LjJMVauXMkzzzzDY489RsWKFYFQC5i4380330yzZs1o06YN8+bNA+C9997jwAMPZP/99+eoo47KXP7CCy9wySWXAHDuuedy2WWXcfDBB7PrrrvyxhtvJC2XgQMHctJJJ2U+/u2331i+fDl33XUXgwZtzMGXL1/Oeeedx7777st+++3Hm2++CcCHH35IixYtaNasGUceeWSu/4eM8t59993ZddddqVChAl26dOGdd97ZbLuDDz6YmjVrAtCmTRtmz54NhKS9TZs2mQnvYYcdxtChQwFo2LAhCxcu5K+//spTLCIlhjucdx60aRNGDRQREZGk4pgH6yjgZ3efnWylmVU1s2oZ94EOwA9FGF+h6NKlC4MHD2bVqlV89913HHjggZnr9tprL8aMGcM333zDHXfcwU033ZS57osvvuDFF19k1KhRmcs+//xzevXqxTvvvEO9evU499xzGTJkCN9//z3r1q3jqaeeon379nz55ZesWLECCM3dstYwTZs2jZ133pltt902acwrVqygTZs2fPvttxx66KGZTRzbtWvHl19+yTfffEOXLl24//77k+4/d+5cxo4dy/vvv88NN9yw2fo1a9Ywffp0GjVqlLksI/k85JBDmDp1KvOjWsU777yT6tWr8/333/Pdd99xxBFHsGDBAi688ELefPNNvv3228ymk59++inNmzff7HbwwQcD8Oeff7LTTjtlnrNBgwb8+eefSZ9DhgEDBnDssccC0LRpU8aMGcPChQtZuXIlw4YN448//sjctkWLFowbNy7H44mUOPffD2+8ATfeCAk1ziIiIrKpwhymfRCQBuxgZrOB29x9ANCFLM0Dzawe8Ky7HwfUAYaGcTAoB7zq7h8WWGDp6fybXRPB3OywA2xhX4L99tuPGTNmMGjQII477rhN1i1ZsoTu3bvz66+/YmasXbs2c1379u3ZbrvtMh//9NNP9OzZkxEjRlCvXj2+/fZbdtllF/bYYw8AunfvzhNPPMEVV1zBMcccw3vvvcfpp5/OBx98kG0ilJ0KFSpkNnU74IADGDlyJACzZ8+mc+fOzJ07lzVr1rDLLrsk3f/kk0+mTJkyNGnSJLOWK9Hff/+9SdNAgMGDBzN06FDKlCnDqaeeyuuvv07v3r35+OOPGTx4cOZ2NWvW5L333uPQQw/NPH9GOR1++OFMnjw52+fl7pstsxwmR/30008ZMGAAY8eOBWDvvffm+uuvp3379myzzTY0a9aMcuU2vpVq167NnDlzsj2eSIkzYgTcdBN07gxXXx13NCIiIsVaYY4i2DWb5ecmWTYHOC66Px1oVlhxxenEE0/kmmuuIT09nYULF2Yu/+9//8vhhx/O0KFDmTFjxib9FapWrbrJMerWrcuqVav45ptvqFevXtJkIUPnzp154okn2G677WjVqtVmSeXuu+/OrFmzkg74AVC+fPnMxKNs2bKsW7cOgEsvvZSrrrqKE088kfT0dPr06ZN0/4xmh5A8qalcuTKrVq3KfPzdd9/x66+/0r59eyDUcO2666707t0bd98sCUq2DEJCdOWVV262vEqVKnz++ec0aNBgkxqn2bNnU69evaTP4YcffuCCCy5g+PDhbL/99pnLe/ToQY8ePQC46aabaNCgQea6VatWUbly5aTHEylxZs6Erl1hn31gwADI4ccIERERiaeJYPFVp07+lufT+eefz6233po5El2GJUuWUL9+fSD0Y8pJjRo1+OCDD7jppptIT09nr732YsaMGUyLRjl8+eWXM0ewS0tLY9KkSTzzzDNJB6CoUqUKPXr04LLLLmPNmjVAaNb3yiuv5BhDYrwvvvhi7k88GzVr1mT9+vWZSdagQYPo06cPM2bMYMaMGcyZM4c///yTmTNn0qFDBx5//PHMff/55x8OOuggRo8eze+//w7AokWLgI01WFlvn3/+OQCtWrXi119/5ffff2fNmjUMHjyY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\n",
      "text/plain": [
       "<Figure size 864x360 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "=== 规则分析示例 ===\n",
      "订单ID: 0\n",
      "商品数: 7, 金额: 798.58, 用户等级: bronze\n",
      "用户年龄: 25, 购买频率: 6.03, 退货率: 0.08\n",
      "设备类型: mobile, 位置风险: 0.06, IP风险: 0.87\n",
      "规则评估结果:\n",
      "- High Item Count: 未触发\n",
      "- Low Order Value: 未触发\n",
      "- Bronze User: 触发\n",
      "- Young User: 未触发\n",
      "- High Purchase Freq: 未触发\n",
      "- High Return Rate: 未触发\n",
      "- Mobile Device: 触发\n",
      "- High Location Risk: 未触发\n",
      "- High IP Risk: 触发\n",
      "风险评分: 0.21, 最终判定: 低风险\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import timeit\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.metrics import accuracy_score, classification_report\n",
    "import pandas as pd\n",
    "import random\n",
    "\n",
    "# ================== 数据生成 ==================\n",
    "def generate_orders(num_orders=5000):\n",
    "    \"\"\"生成模拟电商订单数据（9个特征）\"\"\"\n",
    "    np.random.seed(42)\n",
    "    orders = []\n",
    "    for i in range(num_orders):\n",
    "        items = np.random.randint(1, 20)  # 商品数1-20\n",
    "        value = np.random.uniform(10, 1000)  # 订单金额10-1000\n",
    "        user_level = np.random.choice(['bronze', 'silver', 'gold'], p=[0.6, 0.3, 0.1])\n",
    "        user_age = np.random.randint(18, 70)  # 用户年龄\n",
    "        purchase_freq = np.random.uniform(0.1, 10.0)  # 月购买频率\n",
    "        return_rate = np.random.uniform(0, 0.5)  # 历史退货率\n",
    "        device_type = np.random.choice(['mobile', 'desktop', 'tablet'], p=[0.7, 0.25, 0.05])\n",
    "        location_risk = np.random.uniform(0, 1)  # 地理位置风险\n",
    "        ip_risk = np.random.uniform(0, 1)  # IP风险评分\n",
    "        \n",
    "        # 更复杂的欺诈规则\n",
    "        fraud_prob = (\n",
    "            0.05 + \n",
    "            0.15 * (items > 15) + \n",
    "            0.10 * (value < 100) + \n",
    "            0.08 * (user_level == 'bronze') +\n",
    "            0.05 * (user_age < 25) +\n",
    "            0.07 * (purchase_freq > 8) +\n",
    "            0.12 * (return_rate > 0.3) +\n",
    "            0.05 * (device_type == 'mobile') +\n",
    "            0.10 * (location_risk > 0.7) +\n",
    "            0.08 * (ip_risk > 0.8)\n",
    "        )\n",
    "        is_fraud = np.random.random() < fraud_prob\n",
    "        \n",
    "        orders.append({\n",
    "            'order_id': i,\n",
    "            'items': items,\n",
    "            'value': value,\n",
    "            'user_level': user_level,\n",
    "            'user_age': user_age,\n",
    "            'purchase_freq': purchase_freq,\n",
    "            'return_rate': return_rate,\n",
    "            'device_type': device_type,\n",
    "            'location_risk': location_risk,\n",
    "            'ip_risk': ip_risk,\n",
    "            'is_fraud': is_fraud  # 真实标签\n",
    "        })\n",
    "    return orders\n",
    "\n",
    "# ================== 广义映射实现（9特征） ==================\n",
    "class RiskRule:\n",
    "    \"\"\"风险规则基类\"\"\"\n",
    "    def __init__(self, name, weight):\n",
    "        self.name = name\n",
    "        self.weight = weight\n",
    "    \n",
    "    def evaluate(self, order) -> bool:\n",
    "        \"\"\"评估规则（子类实现）\"\"\"\n",
    "        raise NotImplementedError\n",
    "\n",
    "class QuantityRule(RiskRule):\n",
    "    \"\"\"商品数量规则\"\"\"\n",
    "    def evaluate(self, order):\n",
    "        return order['items'] > 15\n",
    "\n",
    "class ValueRule(RiskRule):\n",
    "    \"\"\"订单金额规则\"\"\"\n",
    "    def evaluate(self, order):\n",
    "        return order['value'] < 100\n",
    "\n",
    "class UserLevelRule(RiskRule):\n",
    "    \"\"\"用户等级规则\"\"\"\n",
    "    def evaluate(self, order):\n",
    "        return order['user_level'] == 'bronze'\n",
    "\n",
    "class UserAgeRule(RiskRule):\n",
    "    \"\"\"用户年龄规则\"\"\"\n",
    "    def evaluate(self, order):\n",
    "        return order['user_age'] < 25\n",
    "\n",
    "class PurchaseFreqRule(RiskRule):\n",
    "    \"\"\"购买频率规则\"\"\"\n",
    "    def evaluate(self, order):\n",
    "        return order['purchase_freq'] > 8\n",
    "\n",
    "class ReturnRateRule(RiskRule):\n",
    "    \"\"\"退货率规则\"\"\"\n",
    "    def evaluate(self, order):\n",
    "        return order['return_rate'] > 0.3\n",
    "\n",
    "class DeviceRule(RiskRule):\n",
    "    \"\"\"设备类型规则\"\"\"\n",
    "    def evaluate(self, order):\n",
    "        return order['device_type'] == 'mobile'\n",
    "\n",
    "class LocationRiskRule(RiskRule):\n",
    "    \"\"\"地理位置风险规则\"\"\"\n",
    "    def evaluate(self, order):\n",
    "        return order['location_risk'] > 0.7\n",
    "\n",
    "class IPRiskRule(RiskRule):\n",
    "    \"\"\"IP风险规则\"\"\"\n",
    "    def evaluate(self, order):\n",
    "        return order['ip_risk'] > 0.8\n",
    "\n",
    "class RiskSystem:\n",
    "    \"\"\"广义映射风控系统（9规则）\"\"\"\n",
    "    def __init__(self):\n",
    "        self.rules = [\n",
    "            QuantityRule('High Item Count', 0.15),\n",
    "            ValueRule('Low Order Value', 0.10),\n",
    "            UserLevelRule('Bronze User', 0.08),\n",
    "            UserAgeRule('Young User', 0.05),\n",
    "            PurchaseFreqRule('High Purchase Freq', 0.07),\n",
    "            ReturnRateRule('High Return Rate', 0.12),\n",
    "            DeviceRule('Mobile Device', 0.05),\n",
    "            LocationRiskRule('High Location Risk', 0.10),\n",
    "            IPRiskRule('High IP Risk', 0.08)\n",
    "        ]\n",
    "        self.threshold = 0.5  # 风险阈值\n",
    "    \n",
    "    def process(self, order):\n",
    "        \"\"\"处理订单\"\"\"\n",
    "        risk_score = 0\n",
    "        rule_results = {}\n",
    "        \n",
    "        for rule in self.rules:\n",
    "            result = rule.evaluate(order)\n",
    "            if result:\n",
    "                risk_score += rule.weight\n",
    "            rule_results[rule.name] = result\n",
    "        \n",
    "        is_risk = risk_score > self.threshold\n",
    "        return is_risk, risk_score, rule_results\n",
    "\n",
    "# ================== 马尔科夫链实现（9特征） ==================\n",
    "def mk_process(orders):\n",
    "    \"\"\"马尔科夫链风控系统（扩展特征）\"\"\"\n",
    "    results = []\n",
    "    # 定义状态转移规则\n",
    "    transition = {\n",
    "        'start': [('check_quantity', 1.0)],\n",
    "        'check_quantity': [\n",
    "            ('check_value', 0.7),\n",
    "            ('high_risk', 0.3)\n",
    "        ],\n",
    "        'check_value': [\n",
    "            ('check_user_level', 0.6),\n",
    "            ('high_risk', 0.4)\n",
    "        ],\n",
    "        'check_user_level': [\n",
    "            ('check_user_age', 0.5),\n",
    "            ('high_risk', 0.5)\n",
    "        ],\n",
    "        'check_user_age': [\n",
    "            ('check_purchase_freq', 0.6),\n",
    "            ('high_risk', 0.4)\n",
    "        ],\n",
    "        'check_purchase_freq': [\n",
    "            ('check_return_rate', 0.7),\n",
    "            ('high_risk', 0.3)\n",
    "        ],\n",
    "        'check_return_rate': [\n",
    "            ('check_device', 0.6),\n",
    "            ('high_risk', 0.4)\n",
    "        ],\n",
    "        'check_device': [\n",
    "            ('check_location', 0.7),\n",
    "            ('high_risk', 0.3)\n",
    "        ],\n",
    "        'check_location': [\n",
    "            ('check_ip', 0.6),\n",
    "            ('high_risk', 0.4)\n",
    "        ],\n",
    "        'check_ip': [\n",
    "            ('low_risk', 0.8),\n",
    "            ('high_risk', 0.2)\n",
    "        ]\n",
    "    }\n",
    "    \n",
    "    for order in orders:\n",
    "        state = 'start'\n",
    "        while state not in ['low_risk', 'high_risk']:\n",
    "            # 根据订单特征调整转移概率\n",
    "            if state == 'check_quantity' and order['items'] > 15:\n",
    "                transition['check_quantity'] = [('high_risk', 1.0)]\n",
    "            elif state == 'check_value' and order['value'] < 100:\n",
    "                transition['check_value'] = [('high_risk', 1.0)]\n",
    "            elif state == 'check_user_level' and order['user_level'] == 'bronze':\n",
    "                transition['check_user_level'] = [('high_risk', 1.0)]\n",
    "            elif state == 'check_user_age' and order['user_age'] < 25:\n",
    "                transition['check_user_age'] = [('high_risk', 1.0)]\n",
    "            elif state == 'check_purchase_freq' and order['purchase_freq'] > 8:\n",
    "                transition['check_purchase_freq'] = [('high_risk', 1.0)]\n",
    "            elif state == 'check_return_rate' and order['return_rate'] > 0.3:\n",
    "                transition['check_return_rate'] = [('high_risk', 1.0)]\n",
    "            elif state == 'check_device' and order['device_type'] == 'mobile':\n",
    "                transition['check_device'] = [('high_risk', 1.0)]\n",
    "            elif state == 'check_location' and order['location_risk'] > 0.7:\n",
    "                transition['check_location'] = [('high_risk', 1.0)]\n",
    "            elif state == 'check_ip' and order['ip_risk'] > 0.8:\n",
    "                transition['check_ip'] = [('high_risk', 1.0)]\n",
    "            \n",
    "            # 状态转移\n",
    "            rand_val = np.random.random()\n",
    "            cumulative = 0.0\n",
    "            for next_state, prob in transition[state]:\n",
    "                cumulative += prob\n",
    "                if rand_val <= cumulative:\n",
    "                    state = next_state\n",
    "                    break\n",
    "        \n",
    "        results.append(state == 'high_risk')\n",
    "    return np.array(results)\n",
    "\n",
    "# ================== 性能测试 ==================\n",
    "def performance_test(orders):\n",
    "    \"\"\"时间复杂度对比测试\"\"\"\n",
    "    sizes = [100, 300, 1000, 3000, 5000]\n",
    "    gm_times, mk_times = [], []\n",
    "    \n",
    "    # 初始化系统\n",
    "    gm_system = RiskSystem()\n",
    "    \n",
    "    for n in sizes:\n",
    "        if n > len(orders):\n",
    "            continue\n",
    "            \n",
    "        subset = orders[:n]\n",
    "        \n",
    "        # 广义映射测试\n",
    "        gm_start = timeit.default_timer()\n",
    "        for order in subset:\n",
    "            gm_system.process(order)\n",
    "        gm_time = (timeit.default_timer() - gm_start) * 1000  # 毫秒\n",
    "        gm_times.append(gm_time)\n",
    "        \n",
    "        # 马尔科夫链测试\n",
    "        mk_start = timeit.default_timer()\n",
    "        mk_process(subset)\n",
    "        mk_time = (timeit.default_timer() - mk_start) * 1000\n",
    "        mk_times.append(mk_time)\n",
    "        \n",
    "        print(f\"测试规模: {n}, GM时间: {gm_time:.2f}ms, MK时间: {mk_time:.2f}ms\")\n",
    "    \n",
    "    return sizes[:len(gm_times)], gm_times, mk_times\n",
    "\n",
    "# ================== 可视化 ==================\n",
    "def plot_results(sizes, gm_times, mk_times, gm_acc, mk_acc):\n",
    "    plt.figure(figsize=(12, 5))\n",
    "    \n",
    "    # 耗时对比\n",
    "    plt.subplot(1, 2, 1)\n",
    "    plt.plot(sizes, gm_times, 'b-o', label=f'Generalized Mapping (Acc={gm_acc:.2f})')\n",
    "    plt.plot(sizes, mk_times, 'r--s', label=f'Markov Chain (Acc={mk_acc:.2f})')\n",
    "    plt.xlabel('Number of Orders')\n",
    "    plt.ylabel('Processing Time (ms)')\n",
    "    plt.title('Time Complexity Comparison (9 Features)')\n",
    "    plt.grid(True)\n",
    "    plt.legend()\n",
    "    \n",
    "    # 准确率对比\n",
    "    plt.subplot(1, 2, 2)\n",
    "    plt.bar(['Generalized Mapping', 'Markov Chain'], [gm_acc, mk_acc], color=['blue', 'red'])\n",
    "    plt.ylim(0, 1)\n",
    "    plt.ylabel('Accuracy')\n",
    "    plt.title('Risk Detection Accuracy (9 Features)')\n",
    "    plt.grid(True)\n",
    "    \n",
    "    plt.tight_layout()\n",
    "    plt.savefig('ecommerce_9features_performance.png', dpi=300)\n",
    "    plt.show()\n",
    "\n",
    "# ================== 主程序 ==================\n",
    "if __name__ == \"__main__\":\n",
    "    print(\"生成模拟订单数据（9个特征）...\")\n",
    "    orders = generate_orders(5000)  # 生成5000笔订单\n",
    "    y_true = np.array([o['is_fraud'] for o in orders])\n",
    "    \n",
    "    print(\"\\n=== 性能测试 ===\")\n",
    "    sizes, gm_times, mk_times = performance_test(orders)\n",
    "    \n",
    "    print(\"\\n=== 准确率验证 ===\")\n",
    "    # 广义映射处理\n",
    "    gm_system = RiskSystem()\n",
    "    y_pred_gm = []\n",
    "    for order in orders:\n",
    "        is_risk, _, _ = gm_system.process(order)\n",
    "        y_pred_gm.append(is_risk)\n",
    "    y_pred_gm = np.array(y_pred_gm)\n",
    "    \n",
    "    # 马尔科夫链处理\n",
    "    y_pred_mk = mk_process(orders)\n",
    "    \n",
    "    # 计算准确率\n",
    "    gm_acc = accuracy_score(y_true, y_pred_gm)\n",
    "    mk_acc = accuracy_score(y_true, y_pred_mk)\n",
    "    \n",
    "    print(\"\\n广义映射分类报告:\")\n",
    "    print(classification_report(y_true, y_pred_gm))\n",
    "    \n",
    "    print(\"\\n马尔科夫链分类报告:\")\n",
    "    print(classification_report(y_true, y_pred_mk))\n",
    "    \n",
    "    # 可视化结果\n",
    "    plot_results(sizes, gm_times, mk_times, gm_acc, mk_acc)\n",
    "    \n",
    "    # 输出规则分析示例\n",
    "    print(\"\\n=== 规则分析示例 ===\")\n",
    "    sample_order = orders[0]\n",
    "    is_risk, risk_score, rule_results = gm_system.process(sample_order)\n",
    "    print(f\"订单ID: {sample_order['order_id']}\")\n",
    "    print(f\"商品数: {sample_order['items']}, 金额: {sample_order['value']:.2f}, 用户等级: {sample_order['user_level']}\")\n",
    "    print(f\"用户年龄: {sample_order['user_age']}, 购买频率: {sample_order['purchase_freq']:.2f}, 退货率: {sample_order['return_rate']:.2f}\")\n",
    "    print(f\"设备类型: {sample_order['device_type']}, 位置风险: {sample_order['location_risk']:.2f}, IP风险: {sample_order['ip_risk']:.2f}\")\n",
    "    print(\"规则评估结果:\")\n",
    "    for rule, result in rule_results.items():\n",
    "        print(f\"- {rule}: {'触发' if result else '未触发'}\")\n",
    "    print(f\"风险评分: {risk_score:.2f}, 最终判定: {'高风险' if is_risk else '低风险'}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
